package com.shey.imageloader.bean;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

import com.shey.utils.BitmapDecoder;
import com.shey.imageloader.disklrucache.IOUtil;
import com.shey.imageloader.impl.IBitmapCache;
import com.shey.imageloader.disklrucache.DiskLruCache;
import com.shey.utils.Md5Helper;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by SheyChen on 2015/12/2 15:07.
 * Email 1768037936@qq.com
 * 磁盘缓存
 */
public class DiskCache implements IBitmapCache {

    public static final String IMAGE_DISK_CACHE="BitmapCache";
    private static final int MB = 1024 * 1024;
    public static long cacheMaxSize = 50 * MB;
    private static DiskCache mDiskCache;
    private DiskLruCache mDiskLruCache;

    private DiskCache(Context context) {
        initDiskCache(context);
    }

    public static DiskCache getDiskCache(Context context) {
        if (mDiskCache == null) {
            synchronized (DiskCache.class) {
                if (mDiskCache == null) {
                    mDiskCache = new DiskCache(context);
                }
            }
        }
        return mDiskCache;
    }

    /**
     * 获取缓存目录
     * @param context
     * @param fileName
     * @return
     */
    public File getDiskCacheDir(Context context, String fileName) {

        String cachePath;

        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }

        return new File(cachePath + File.separator + fileName);
    }

    @Override
    public Bitmap get(final BitmapRequest bitmapRequest) {

        BitmapDecoder bitmapDecoder = new BitmapDecoder() {
            @Override
            public Bitmap decodeBitmapWithOption(BitmapFactory.Options options) {
                final InputStream inputStream = getInputStream(bitmapRequest.imageUriMD5);
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
                IOUtil.closeQuietly(inputStream);
                return bitmap;
            }
        };
        return bitmapDecoder.decodeBitmap(200,200);
    }

    @Override
    public void put(BitmapRequest bitmapRequest, Bitmap bitmap) {

        DiskLruCache.Editor editor = null;
        try {
            editor = mDiskLruCache.edit(bitmapRequest.imageUriMD5);
            if (editor != null) {
                OutputStream outputStream = editor.newOutputStream(0);
                if (writeBitmapToDisk(bitmap, outputStream)) {
                    editor.commit();
                } else {
                    editor.abort();
                }
                IOUtil.closeQuietly(outputStream);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void remove(BitmapRequest bitmapRequest) {
        try {
            mDiskLruCache.remove(Md5Helper.toMD5(bitmapRequest.imageUri)); //TODO 把Uri转换成MD5值
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isExist(String md5) {
        boolean isExist = false;

        DiskLruCache.Snapshot snapshot;
        try {
            snapshot = mDiskLruCache.get(md5);
            if (snapshot != null) {
                isExist = true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return isExist;
    }

    /**
     * 初始化磁盘缓存的目录，版本号，大小
     * @param context
     */
    private void initDiskCache(Context context) {

        try {
            File cacheFile = getDiskCacheDir(context, IMAGE_DISK_CACHE);
            if (!cacheFile.exists()) {
                cacheFile.mkdirs();
            }
            mDiskLruCache = DiskLruCache.open(cacheFile, getAppVersion(context), 1, cacheMaxSize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取App的版本号
     * @param context
     * @return
     */
    private int getAppVersion(Context context) {

        try {
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return 1;
    }

    private InputStream getInputStream(String md5) {

        DiskLruCache.Snapshot snapshot;
        try {
            snapshot = mDiskLruCache.get(md5);
            if (snapshot != null) {
                return snapshot.getInputStream(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 把位图写入磁盘，//TODO 后续需要对图片的尺寸进行压缩，防止过大
     * @param bitmap
     * @param outputStream
     * @return
     */
    private boolean writeBitmapToDisk(Bitmap bitmap, OutputStream outputStream) {
        BufferedOutputStream bos = new BufferedOutputStream(outputStream, 8 * 1024);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
        boolean result = true;
        try {
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
        } finally {
            IOUtil.closeQuietly(bos);
        }
        return result;
    }
}
